package com.infinitus.nginxInfo.domain.nginxinfo;

import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.lang3.StringUtils;

import com.alibaba.fastjson.JSONObject;
import com.infinitus.nginxInfo.config.StaticCache;
import com.infinitus.nginxInfo.service.util.Base64Coder;
import com.infinitus.nginxInfo.service.util.TimeUtil;
import com.infinitus.nginxInfo.task.FilterRules;


/**
 * @author satoshi
 *
 */
public class NginxInfo implements Serializable{
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1446261316939183271L;

	public static final String ITEM_TERMINATED = "\001";

	public static final String COLLECTION_TERMINATED = "\002";
	
	public static final String HEAD_TERMINATED = "\\|";

	public static final String MAP_TERMINATED = "\003";

	
	private Fields fields;
	private Agent2 agent2;
	private Geoip geoip;
	
	private String body_bytes_send; //返回大小(不包括头部)
	private String bytes_send; //返回大小(包括头部)
	private String domain;	//客户端域名(domain)
	private String http_version;	//http版本
	private String real_ip;	//客户端IP(real_ip)
	private String referrer;	//客户引荐(referrer)
	private String request;	//当前请求地址(request)
	private String ident;	//身份
	private String verb; //请求方法
	private String request_length;	//请求大小
	private String request_time;	//响应时间
	private String request_uri;	//页面路径(request_uri)
	private String response_status;	//响应状态
	private String upstream_content_type;
	private String upstream_status;	//集群服务器返回状态
	private String upstream_cache_status;
	private String upstream_response_time; //集群响应时间
	private String[] x_forword;
	
	private String sugo_operator;	//运营商
	private String page_name;	//页面名称
	private String event_type;	//事件类型
	private String event_name;	//事件名称
	private String event_label;	//事件源文本
	private String EventValue;
	private String EventValueType;
	private String UserID;
	private String UserAtt;
	private String device_id;	//设备ID
	private String distinct_id;	//用户唯一ID
	private String session_id;	//会话ID
	private String sugo_args;	//请求参数
	private String sugo_http_cookie;	//HttpCookie
	
	private String event_time;
	private String YearMonth;
	private String DayOfWeek;
	private String EventDate;
	private String EventHour;
	private String YearWeek;
	private String Media;
	private String Source;
	private String Creative;
	private String Campaign;
	private String Content;
	private String ColumnName;
	
	public NginxInfo() {
		super();
	}
	
	
	
	public Fields getFields() {
		return fields;
	}



	public void setFields(Fields fields) {
		this.fields = fields;
	}



	public Agent2 getAgent2() {
		return agent2;
	}



	public void setAgent2(Agent2 agent2) {
		this.agent2 = agent2;
	}



	public Geoip getGeoip() {
		return geoip;
	}



	public void setGeoip(Geoip geoip) {
		this.geoip = geoip;
	}



	public String getBody_bytes_send() {
		return body_bytes_send;
	}



	public void setBody_bytes_send(String body_bytes_send) {
		this.body_bytes_send = body_bytes_send;
	}



	public String getBytes_send() {
		return bytes_send;
	}



	public void setBytes_send(String bytes_send) {
		this.bytes_send = bytes_send;
	}



	public String getDomain() {
		return domain;
	}



	public void setDomain(String domain) {
		this.domain = domain;
	}



	public String getHttp_version() {
		return http_version;
	}



	public void setHttp_version(String http_version) {
		this.http_version = http_version;
	}



	public String getReal_ip() {
		return real_ip;
	}



	public void setReal_ip(String real_ip) {
		this.real_ip = real_ip;
	}



	public String getReferrer() {
		return referrer;
	}



	public void setReferrer(String referrer) {
		this.referrer = referrer;
	}



	public String getRequest() {
		return request;
	}



	public void setRequest(String request) {
		this.request = request;
	}



	public String getVerb() {
		return verb;
	}



	public void setVerb(String verb) {
		this.verb = verb;
	}



	public String getRequest_length() {
		return request_length;
	}



	public void setRequest_length(String request_length) {
		this.request_length = request_length;
	}



	public String getRequest_time() {
		return request_time;
	}



	public void setRequest_time(String request_time) {
		this.request_time = request_time;
	}



	public String getRequest_uri() {
		return request_uri;
	}



	public void setRequest_uri(String request_uri) {
		this.request_uri = request_uri;
	}



	public String getResponse_status() {
		return response_status;
	}



	public void setResponse_status(String response_status) {
		this.response_status = response_status;
	}



	public String getUpstream_content_type() {
		return upstream_content_type;
	}



	public void setUpstream_content_type(String upstream_content_type) {
		this.upstream_content_type = upstream_content_type;
	}



	public String getUpstream_status() {
		return upstream_status;
	}



	public void setUpstream_status(String upstream_status) {
		this.upstream_status = upstream_status;
	}



	public String getUpstream_cache_status() {
		return upstream_cache_status;
	}



	public void setUpstream_cache_status(String upstream_cache_status) {
		this.upstream_cache_status = upstream_cache_status;
	}



	public String getUpstream_response_time() {
		return upstream_response_time;
	}



	public void setUpstream_response_time(String upstream_response_time) {
		this.upstream_response_time = upstream_response_time;
	}



	public String[] getX_forword() {
		return x_forword;
	}



	public void setX_forword(String[] x_forword) {
		this.x_forword = x_forword;
	}



	public String getSugo_operator() {
		return sugo_operator;
	}



	public void setSugo_operator(String sugo_operator) {
		this.sugo_operator = sugo_operator;
	}



	public String getPage_name() {
		return page_name;
	}



	public void setPage_name(String page_name) {
		this.page_name = page_name;
	}



	public String getEvent_type() {
		return event_type;
	}



	public void setEvent_type(String event_type) {
		this.event_type = event_type;
	}



	public String getEvent_name() {
		return event_name;
	}



	public void setEvent_name(String event_name) {
		this.event_name = event_name;
	}



	public String getEvent_label() {
		return event_label;
	}



	public void setEvent_label(String event_label) {
		this.event_label = event_label;
	}



	public String getEventValue() {
		return EventValue;
	}



	public void setEventValue(String eventValue) {
		EventValue = eventValue;
	}



	public String getEventValueType() {
		return EventValueType;
	}



	public void setEventValueType(String eventValueType) {
		EventValueType = eventValueType;
	}



	public String getUserID() {
		return UserID;
	}



	public void setUserID(String userID) {
		UserID = userID;
	}



	public String getUserAtt() {
		return UserAtt;
	}



	public void setUserAtt(String userAtt) {
		UserAtt = userAtt;
	}



	public String getDevice_id() {
		return device_id;
	}



	public void setDevice_id(String device_id) {
		this.device_id = device_id;
	}



	public String getDistinct_id() {
		return distinct_id;
	}



	public void setDistinct_id(String distinct_id) {
		this.distinct_id = distinct_id;
	}



	public String getSession_id() {
		return session_id;
	}



	public void setSession_id(String session_id) {
		this.session_id = session_id;
	}



	public String getSugo_args() {
		return sugo_args;
	}



	public void setSugo_args(String sugo_args) {
		this.sugo_args = sugo_args;
	}



	public String getSugo_http_cookie() {
		return sugo_http_cookie;
	}



	public void setSugo_http_cookie(String sugo_http_cookie) {
		this.sugo_http_cookie = sugo_http_cookie;
	}



	public String getEvent_time() {
		return event_time;
	}



	public void setEvent_time(String event_time) {
		this.event_time = event_time;
	}



	public String getYearMonth() {
		return YearMonth;
	}



	public void setYearMonth(String yearMonth) {
		YearMonth = yearMonth;
	}



	public String getDayOfWeek() {
		return DayOfWeek;
	}



	public void setDayOfWeek(String dayOfWeek) {
		DayOfWeek = dayOfWeek;
	}



	public String getEventDate() {
		return EventDate;
	}



	public void setEventDate(String eventDate) {
		EventDate = eventDate;
	}



	public String getEventHour() {
		return EventHour;
	}



	public void setEventHour(String eventHour) {
		EventHour = eventHour;
	}



	public String getYearWeek() {
		return YearWeek;
	}



	public void setYearWeek(String yearWeek) {
		YearWeek = yearWeek;
	}



	public String getMedia() {
		return Media;
	}



	public void setMedia(String media) {
		Media = media;
	}



	public String getSource() {
		return Source;
	}



	public void setSource(String source) {
		Source = source;
	}



	public String getCreative() {
		return Creative;
	}



	public void setCreative(String creative) {
		Creative = creative;
	}



	public String getCampaign() {
		return Campaign;
	}



	public void setCampaign(String campaign) {
		Campaign = campaign;
	}



	public String getContent() {
		return Content;
	}



	public void setContent(String content) {
		Content = content;
	}



	public String getColumnName() {
		return ColumnName;
	}



	public void setColumnName(String columnName) {
		ColumnName = columnName;
	}



	public String getIdent() {
		return ident;
	}



	public void setIdent(String ident) {
		this.ident = ident;
	}



	public void setEvent_time(Long time) {
		Date date = new Date();
		try{
			Date eventTime = new Date(time);
			if(eventTime.before(date)){
				date = eventTime;
			}
		}catch(Exception e){
			
		}
		this.event_time = ""+date.getTime();
		String dateStr = TimeUtil.dateTimeFormat.format(date);
		YearMonth = dateStr.substring(0, 7);
		EventDate = dateStr.substring(0, 10);
		EventHour = dateStr.substring(11, 13);
		DayOfWeek = date.toString().substring(0, 3);
	}
	

	public static NginxInfo converts(String value) {
		NginxInfo item = null;
		try{
			JSONObject json = JSONObject.parseObject(value);
			item = JSONObject.toJavaObject(json, NginxInfo.class);
			String time = json.getString("@timestamp");
			item.setEvent_time(TimeUtil.isoToUnix(time));
		}catch(Exception e){
			e.printStackTrace();
			System.out.println("解析错误："+value);
		}
		return item;
	}
	
	private String toUpperCase(String str){
		if(str==null || "".equals(str.trim())){
			return "";
		}
		return str.toUpperCase();
	}
	
	private String toLowerCase(String str){
		if(str==null || "".equals(str.trim())){
			return "";
		}
		return str.toLowerCase();
	}
	
	public static final Map<String,String> FILEDTYPE_MAP;
	static{
		FILEDTYPE_MAP = new HashMap<String, String>();
		FILEDTYPE_MAP.put("business_name","s");
		FILEDTYPE_MAP.put("app_name","s");
		FILEDTYPE_MAP.put("app_version","s");
		FILEDTYPE_MAP.put("file_type_name","s");
		FILEDTYPE_MAP.put("machine_name","s");
		FILEDTYPE_MAP.put("system_name","s");
		FILEDTYPE_MAP.put("system_version","s");
		FILEDTYPE_MAP.put("device_brand","s");
		FILEDTYPE_MAP.put("device_model","s");
		FILEDTYPE_MAP.put("sugo_nation","s");
		FILEDTYPE_MAP.put("sugo_province","s");
		FILEDTYPE_MAP.put("sugo_city","s");
		
		FILEDTYPE_MAP.put("sugo_latitude","f");
		FILEDTYPE_MAP.put("sugo_longitude","f");
		FILEDTYPE_MAP.put("body_bytes_send","f");
		FILEDTYPE_MAP.put("bytes_send","f");
		FILEDTYPE_MAP.put("host","s");
		FILEDTYPE_MAP.put("http_version","s");
		FILEDTYPE_MAP.put("sugo_ip","s");
		FILEDTYPE_MAP.put("referrer","s");
		FILEDTYPE_MAP.put("current_url","s");
		FILEDTYPE_MAP.put("verb","s");
		FILEDTYPE_MAP.put("request_length","f");
		FILEDTYPE_MAP.put("request_time","f");
		FILEDTYPE_MAP.put("path_name","s");
		FILEDTYPE_MAP.put("response_status","s");
		FILEDTYPE_MAP.put("upstream_content_type","s");
		FILEDTYPE_MAP.put("upstream_status","s");
		FILEDTYPE_MAP.put("upstream_cache_status","s");
		FILEDTYPE_MAP.put("upstream_response_time","f");
		FILEDTYPE_MAP.put("x_forword","s");
		FILEDTYPE_MAP.put("sugo_operator","s");
		FILEDTYPE_MAP.put("page_name","s");
		FILEDTYPE_MAP.put("event_type","s");
		FILEDTYPE_MAP.put("event_name","s");
		FILEDTYPE_MAP.put("event_label","s");
		FILEDTYPE_MAP.put("EventValue","s");
		FILEDTYPE_MAP.put("EventValueType","s");
		FILEDTYPE_MAP.put("UserID","s");
		FILEDTYPE_MAP.put("UserAtt","s");
		FILEDTYPE_MAP.put("device_id","s");
		FILEDTYPE_MAP.put("distinct_id","s");
		FILEDTYPE_MAP.put("session_id","s");
		FILEDTYPE_MAP.put("sugo_args","s");
		FILEDTYPE_MAP.put("sugo_http_cookie","s");
		FILEDTYPE_MAP.put("event_time","d");
		FILEDTYPE_MAP.put("YearMonth","s");
		FILEDTYPE_MAP.put("DayOfWeek","s");
		FILEDTYPE_MAP.put("EventDate","s");
		FILEDTYPE_MAP.put("EventHour","s");
		FILEDTYPE_MAP.put("YearWeek","s");
		FILEDTYPE_MAP.put("Media","s");
		FILEDTYPE_MAP.put("Source","s");
		FILEDTYPE_MAP.put("Creative","s");
		FILEDTYPE_MAP.put("Campaign","s");
		FILEDTYPE_MAP.put("Content","s");
		FILEDTYPE_MAP.put("ColumnName","s");
	}
	
	public Map<String ,Object> toMap(){
		Map<String, Object> map = new HashMap<String, Object>();
		if(fields!=null){
			cutField(map, "business_name", fields.getBusiness_name());
			cutField(map, "app_name", fields.getApplication_name());
			cutField(map, "app_version", fields.getEnvironment_type());
			cutField(map, "file_type_name", fields.getFile_type_name());
			cutField(map, "machine_name", fields.getMachine_name());
		}
		if(agent2!=null){
			cutField(map, "system_name", agent2.getOs_name());
			cutField(map, "system_version", agent2.getOs());
			cutField(map, "device_brand", agent2.getDevice());
			cutField(map, "device_model", agent2.getName());
		}
		if(geoip!=null){
			cutField(map, "sugo_nation", geoip.getCountry_name());
			cutField(map, "sugo_province", geoip.getRegion_name());
			cutField(map, "sugo_city", geoip.getCity_name());
			cutField(map, "sugo_latitude", geoip.getLongitude());
			cutField(map, "sugo_longitude", geoip.getLatitude());
		}
			
		cutField(map, "body_bytes_send", body_bytes_send);
		cutField(map, "bytes_send", bytes_send);
		cutField(map, "host", domain);
		cutField(map, "http_version", http_version);
		cutField(map, "sugo_ip", real_ip);
		cutField(map, "referrer", referrer);
		cutField(map, "current_url", request);
		cutField(map, "verb", verb);
		cutField(map, "request_length", request_length);
		cutField(map, "request_time", request_time);
		cutField(map, "path_name", request_uri);
		cutField(map, "response_status", response_status);
		cutField(map, "upstream_content_type", upstream_content_type);
		cutField(map, "upstream_status", upstream_status);
		cutField(map, "upstream_cache_status", upstream_cache_status);
		cutField(map, "upstream_response_time", upstream_response_time);
		if(x_forword!=null && x_forword.length>0){
			cutField(map, "x_forword", StringUtils.join(x_forword, ","));
		}
		
		cutField(map, "sugo_operator", sugo_operator);
		cutField(map, "page_name", page_name);
		cutField(map, "event_type", event_type);
		cutField(map, "event_name", event_name);
		cutField(map, "event_label", event_label);
		cutField(map, "EventValue", EventValue);
		cutField(map, "EventValueType", EventValueType);
		cutField(map, "UserID", UserID);
		cutField(map, "UserAtt", UserAtt);
		cutField(map, "device_id", device_id);
		cutField(map, "distinct_id", distinct_id);
		cutField(map, "session_id", session_id);
		cutField(map, "sugo_args", sugo_args);
		cutField(map, "sugo_http_cookie", sugo_http_cookie);
			
		cutField(map, "event_time", event_time);
		cutField(map, "YearMonth", YearMonth);
		cutField(map, "DayOfWeek", DayOfWeek);
		cutField(map, "EventDate", EventDate);
		cutField(map, "EventHour", EventHour);
		cutField(map, "YearWeek", YearWeek);
		cutField(map, "Media", Media);
		cutField(map, "Source", Source);
		cutField(map, "Creative", Creative);
		cutField(map, "Campaign", Campaign);
		cutField(map, "Content", Content);
		cutField(map, "ColumnName", ColumnName);
		
		return map;
	}
	
	private void cutField(Map<String, Object> map ,String FieldName,String FieldValue){
		if(FilterRules.isNotBlank(FieldValue)){
			map.put(FieldName, FieldValue );
		}
	}
	
	public static String encrypt(String targetTopic, NginxInfo item) {
		Map<String, Object> map = item.toMap();
		StringBuffer headStr = new StringBuffer();
		StringBuffer bodyStr = new StringBuffer();
		for(Entry<String, Object> entry: map.entrySet()){
			String field = entry.getKey();
			String type = StaticCache.getFiledType(targetTopic+field);
			if(type == null){
				type=NginxInfo.FILEDTYPE_MAP.get(field);
			}
			if(type==null) continue;
			headStr.append(type+"|"+field+",");
			bodyStr.append(entry.getValue()+ NginxInfo.ITEM_TERMINATED);
		}
		if(headStr.length()==0){
			return null;
		}
		String head = headStr.substring(0, headStr.length()-1);
		String body = bodyStr.substring(0, bodyStr.length()-1);
//		System.out.println("日期："+TimeUtil.getCurrentTime()+" 发送topic："+targetTopic +"_etl\r\n发送头："+head+"\r\n内容体："+body);
		return item.getEvent_time()+"\t"+item.getReal_ip()+"\t2\t3\t"+item.getReal_ip()+"\t5\t6\t" +Base64Coder.encodeString(head +NginxInfo.COLLECTION_TERMINATED+body);
	}

}
